package model.map;

import java.util.HashSet;
import java.util.Set;

import model.entity.Avatar;
import model.entity.stats.StatType;

/**
 * The model aspect of FogofWar, to save the shaded and visible tiles.
 */
public class FogOfWar
{
	private GameMap map;
	private Set<Location> visible;
	private Set<Location> shaded;
	private Avatar player;
	private LocationProjection sightLogic;
	
	/**
	 * 
	 * @param map
	 * @param visible
	 * @param shaded
	 * @param player
	 * @param sightLogic
	 */
	public FogOfWar(GameMap map, Avatar player, LocationProjection sightLogic)
	{
		this.map = map;
		this.map.setFogOfWar( this );
		this.visible = new HashSet<Location>();
		this.shaded = new HashSet<Location>();
		this.player = player;
		this.sightLogic = sightLogic;
	}

	public Set<Location> getVisibleLocations()
	{
		return visible;
	}

	public Set<Location> getShadedLocations()
	{
		return shaded;
	}
	
	public boolean isShaded( Location l ) 
	{ 
		return shaded.contains(l); 
	}
	
	public boolean isVisisble( Location l ) 
	{ 
		return visible.contains(l); 
	}

	/**
	 * Updates what's visible and what's shaded.
	 * Should be called every time the Avatar moves.
	 */
	public void update()
	{
		/**
		 * Section to update visible 
		 */
		
		Set<Location> oldVisible = new HashSet<Location>();
		oldVisible.addAll(visible);
		
		visible.clear();
		
		if(player == null)
			return;
		visible.add(player.getLocation());
		
		for(int i = 0; i < player.getStatVal(StatType.SIGHTRANGE); i++)
		{ 
			
			Location[] locs = visible.toArray(new Location[0]);
			
			for(int j = 0; j < locs.length; j++)
			{
				visible.add(sightLogic.projectLocation(locs[j], Direction.SW));
				visible.add(sightLogic.projectLocation(locs[j], Direction.S));
				visible.add(sightLogic.projectLocation(locs[j], Direction.SE));
				visible.add(sightLogic.projectLocation(locs[j], Direction.NW));
				visible.add(sightLogic.projectLocation(locs[j], Direction.N));
				visible.add(sightLogic.projectLocation(locs[j], Direction.NE));
			}
		}
		
		/**
		 * Section to update shaded 
		 */
		
		//Shaded = oldVisible - visible
		
		Location[] locs = oldVisible.toArray(new Location[0]);
		
		for(int j = 0; j < locs.length; j++)
		{
			shaded.add(locs[j]);
		}
		
		locs = visible.toArray(new Location[0]);
		
		for(int j = 0; j < locs.length; j++)
		{
			shaded.remove(locs[j]);
		}
	}

	@Override
	public String toString()
	{
		return "FogOfWar [map=" + map + ", visible=" + visible + ", shaded=" + shaded + ", player=" + player
				+ ", sightLogic=" + sightLogic + "]";
	}
	
	
	
}
